﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.IO;
using Public;

namespace ControlCenterController
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            this.targets = new List<Target>();
        }

        private List<Target> targets;


        private void AppendToTextBoxOutput(string content)
        {
            this.TextBoxOutput.Text += System.Environment.NewLine + content + System.Environment.NewLine;
            this.TextBoxOutput.ScrollToEnd();
        }

        private long Convert(byte[] ipBytes)
        {
            return (ipBytes[0] << 24) + (ipBytes[1] << 16) + (ipBytes[2] << 8) + ipBytes[3];
        }
        private byte[] Convert(long ipLong)
        {
            return new byte[] { (byte)(ipLong >> 24), (byte)(ipLong << 8 >> 24), (byte)(ipLong << 16 >> 24), (byte)(ipLong << 24 >> 24) };
        }

        private void ButtonAdd_Click(object sender, RoutedEventArgs e)
        {
            IPAddress ipFrom,ipTo;
            if (IPAddress.TryParse(this.TextBoxIPFrom.Text, out ipFrom) && IPAddress.TryParse(this.TextBoxIPTo.Text, out ipTo))
            {
                if (ipFrom.GetAddressBytes().Length > 4 || ipTo.GetAddressBytes().Length > 4)
                    this.AppendToTextBoxOutput("Sorry, IPv6 is not supported in this version.");
                else
                {
                    int successCount = 0, count = 0;
                    long ipFromLong = Convert(ipFrom.GetAddressBytes());
                    long ipToLong = Convert(ipTo.GetAddressBytes());
                    for (long currentIPLong = ipFromLong; currentIPLong <= ipToLong; currentIPLong++)
                    {
                        count += 1;
                        Target target = Target.Connect(Convert(currentIPLong));
                        if (target != null)
                        {
                            this.ListBoxTargets.Items.Add(new TargetItem(target, new TargetChannelClosedHandler(delegate(TargetItem Sender)
                            {
                                TargetItem i = Sender as TargetItem;
                                this.ListBoxTargets.Items.Remove(Sender);
                                this.AppendToTextBoxOutput("Connection of " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ") has been closed.");
                            })));
                            successCount += 1;
                        }
                    }
                    this.AppendToTextBoxOutput(successCount.ToString() + " of " + count.ToString() + " has been added successfully.");
                }

            }
            else
                this.AppendToTextBoxOutput("Sorry, at leasy one IP address you entered is not valid");
        }

        private void ButtonDeleteAll_Click(object sender, RoutedEventArgs e)
        {
            List<Target> targets = new List<Target>();
            foreach (TargetItem i in this.ListBoxTargets.Items)
                targets.Add(i.Target);
            foreach (Target i in targets)
                i.CloseChannel();
        }

        private void ButtonSendFiles_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog fileDialog = new Microsoft.Win32.OpenFileDialog();
            fileDialog.Title = "Selecte the files you want to send";
            fileDialog.Multiselect = true;
            if (fileDialog.ShowDialog(this) == true)
            {
                InputPathWindow inputPathWindow = new InputPathWindow("Input a path of directory where your selected files should be placed in the target machines:");
                if (inputPathWindow.ShowDialog() == true)
                {
                    this.AppendToTextBoxOutput("Sending selected file to targets.");
                    string path = inputPathWindow.Path;
                    List<string> files = new List<string>();
                    foreach (TargetItem i in this.ListBoxTargets.SelectedItems)
                    {
                        Result result = i.Target.SendFiles(new List<string>(fileDialog.FileNames), path);
                        if (result.IsSuccessful)
                            this.AppendToTextBoxOutput("Succeed to send files to " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                        else
                        {
                            this.AppendToTextBoxOutput("Failed to send files to " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                            this.AppendToTextBoxOutput("\t"+result.Content);
                            foreach (Exception ex in result.Exceptions)
                            {
                                Exception currentException = ex;
                                string tabs = "\t\t";
                                while (true)
                                {
                                    this.AppendToTextBoxOutput(tabs + currentException.Message);
                                    currentException = currentException.InnerException;
                                    if (currentException == null)
                                        break;
                                    tabs += "\t";
                                }
                            }
                            this.AppendToTextBoxOutput("");
                        }
                    }
                }
            }
        }

        private void ButtonRunProgram_Click(object sender, RoutedEventArgs e)
        {
            RunProgramWindow runProgramWindow = new RunProgramWindow();
            if (runProgramWindow.ShowDialog() == true)
            {
                foreach (TargetItem i in this.ListBoxTargets.SelectedItems)
                {
                    Result result = i.Target.RunProgram(runProgramWindow.Path, runProgramWindow.Arguments);
                    if (result.IsSuccessful)
                        this.AppendToTextBoxOutput("Succeed to run program in " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                    else
                    {
                        this.AppendToTextBoxOutput("Failed to run program in " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                        this.AppendToTextBoxOutput("\t"+result.Content);
                        foreach (Exception ex in result.Exceptions)
                        {
                            Exception currentException = ex;
                            string tabs = "\t\t";
                            while (true)
                            {
                                this.AppendToTextBoxOutput(tabs + currentException.Message);
                                currentException = currentException.InnerException;
                                if (currentException == null)
                                    break;
                                tabs += "\t";
                            }
                        }
                        this.AppendToTextBoxOutput("");
                    }
                }
            }
        }

        private void ButtonRunScripts_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(((TargetItem)this.ListBoxTargets.SelectedItem).Target.RunTerminalScript(new List<string>(new string[] { "dir" })).Content);
        }

        private void ButtonKillAll_Click(object sender, RoutedEventArgs e)
        {
            foreach (TargetItem i in this.ListBoxTargets.SelectedItems)
            {
                Result result = i.Target.KillAllControlledPrograms();
                if (result.IsSuccessful)
                    this.AppendToTextBoxOutput("Success to kill all controlled programs in " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                else
                {
                    this.AppendToTextBoxOutput("Failed to kill controlled program in " + i.Target.MachineName + "(" + i.Target.IPAddress.ToString() + ").");
                    this.AppendToTextBoxOutput("\t"+result.Content);
                    foreach (Exception ex in result.Exceptions)
                    {
                        Exception currentException = ex;
                        string tabs = "\t\t";
                        while (true)
                        {
                            this.AppendToTextBoxOutput(tabs + currentException.Message);
                            currentException = currentException.InnerException;
                            if (currentException == null)
                                break;
                            tabs += "\t";
                        }
                    }
                    this.AppendToTextBoxOutput("");
                }


            }
        }



    }
}
